package com.wsq.function;

import java.io.Serializable;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.regex.Pattern;

import org.javia.arity.Symbols;
import org.javia.arity.SyntaxException;
import org.javia.arity.Util;

public class CalculateSimpleEngine implements Serializable {
    /**
	 * 
	 */
	private static final long serialVersionUID = -7253948452196131954L;

	private String operator;

    private String preOperand;

    private String curOperand;

    private int length;

    private Symbols symbols = new Symbols();
    NumberFormat format;

    public CalculateSimpleEngine() {
	format = NumberFormat.getInstance();
    }

    public void setMaxLength(int maxLength) {
	this.length = maxLength;
    }

    public boolean isValidOperator(String operator) {
	return "+-\u2212\u00d7\u00f7/*%".indexOf(operator) != -1;
    }

    public boolean isValidDigits(String temp) {
	return Pattern.compile("[\\d|\\.|\\,|e]+").matcher(temp).find();
    }

    public boolean isEqualOperator(String temp) {
	return "=".equals(temp);
    }

    public void setOperator(String operator) throws SyntaxException {
	this.operator = operator;
    }

    public void setOperand(String operand) throws ParseException {
	String tempString=analyseOperand(operand);
	if(this.preOperand==null) {
	    this.preOperand=tempString;
	}else {
	    this.curOperand=tempString;
	}
    }
    
    public void resetOperand()  {
	this.preOperand=null;
	this.curOperand=null;
    }

    private String analyseOperand(String operand) throws ParseException {
	operand = operand.toLowerCase();
	int index = operand.indexOf("e");
	String trail = index != -1 ? operand.substring(index) : "";
	String header = index != -1 ? operand.substring(0, index) : operand;
	String value = format.parse(header).toString();
	return value + trail;
    }


    public String calculate(String current) throws ParseException,
	    SyntaxException {
	StringBuffer sb = new StringBuffer();
	sb.append(preOperand);
	sb.append(operator);
	sb.append(analyseOperand(current));
	return Util.doubleToString(symbols.eval(sb.toString()), length, 1);
    }

    public String translate(String current) throws SyntaxException  {
	return Util.doubleToString(symbols.eval(current), length, 1);
    }

    public String calculate() throws SyntaxException {
	StringBuffer sb = new StringBuffer();
	sb.append(preOperand);
	sb.append(operator);
	sb.append(curOperand);
	return Util.doubleToString(symbols.eval(sb.toString()), length, 1);
    }

    public void afterCalculate(String result) {
	this.preOperand = result;
	this.curOperand = null;
    }

    public boolean canCalculate() {
	return preOperand != null && curOperand != null;
    }
}
